<!--
  - SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  - SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
	<CardDetailEntry :label="t('deck', 'Assign a due date to this card…')" data-test="due-date-selector">
		<Calendar v-if="!card.done" slot="icon" :size="20" />
		<CalendarCheck v-else slot="icon" :size="20" />
		<template v-if="!card.done && !card.archived">
			<NcDateTimePickerNative v-if="duedate"
				id="card-duedate-picker"
				v-model="duedate"
				:placeholder="t('deck', 'Set a due date')"
				:hide-label="true"
				type="datetime-local" />
			<NcActions v-if="canEdit"
				:menu-title="!duedate ? t('deck', 'Add due date') : null"
				type="tertiary"
				data-cy-due-date-actions>
				<template v-if="!duedate" #icon>
					<Plus :size="20" />
				</template>
				<NcActionButton v-for="shortcut in reminderOptions"
					:key="shortcut.key"
					close-after-click
					:data-cy-due-date-shortcut="shortcut.key"
					@click="() => selectShortcut(shortcut)">
					{{ shortcut.label }}
				</NcActionButton>
				<NcActionSeparator />

				<NcActionButton v-if="!duedate"
					close-after-click
					data-cy-due-date-pick
					@click="initDate">
					<template #icon>
						<Plus :size="20" />
					</template>
					{{ t('deck', 'Choose a date') }}
				</NcActionButton>
				<NcActionButton v-else
					icon="icon-delete"
					close-after-click
					data-cy-due-date-remove
					@click="removeDue">
					{{ t('deck', 'Remove due date') }}
				</NcActionButton>
			</NcActions>

			<NcButton v-if="!card.done"
				type="secondary"
				class="completed-button"
				@click="changeCardDoneStatus()">
				<template #icon>
					<CheckIcon :size="20" />
				</template>
				{{ t('deck', 'Mark as done') }}
			</NcButton>
		</template>
		<template v-else>
			<div class="done-info">
				<span v-if="card.done" class="done-info--done">
					{{ formatReadableDate(card.done) }}
				</span>
				<span v-if="duedate" class="done-info--duedate" :class="{ 'dimmed': card.done }">
					{{ t('deck', 'Due at:') }}
					{{ formatReadableDate(duedate) }}
				</span>
			</div>
			<div class="due-actions">
				<NcButton v-if="!card.archived"
					type="tertiary"
					:name="t('deck', 'Not done')"
					@click="changeCardDoneStatus()">
					<template #icon>
						<ClearIcon :size="20" />
					</template>
				</NcButton>
				<NcButton type="secondary" @click="archiveUnarchiveCard()">
					<template #icon>
						<ArchiveIcon :size="20" />
					</template>
					{{ card.archived ? t('deck', 'Unarchive card') : t('deck', 'Archive card') }}
				</NcButton>
			</div>
		</template>
	</CardDetailEntry>
</template>

<script>
import { defineComponent } from 'vue'
import {
	NcActionButton,
	NcActions,
	NcActionSeparator,
	NcButton,
	NcDateTimePickerNative,
} from '@nextcloud/vue'
import readableDate from '../../mixins/readableDate.js'
import { getDayNamesMin, getFirstDay, getMonthNamesShort } from '@nextcloud/l10n'
import moment from '@nextcloud/moment'
import ArchiveIcon from 'vue-material-design-icons/ArchiveOutline.vue'
import Plus from 'vue-material-design-icons/Plus.vue'
import Calendar from 'vue-material-design-icons/CalendarOutline.vue'
import CalendarCheck from 'vue-material-design-icons/CalendarCheckOutline.vue'
import CheckIcon from 'vue-material-design-icons/Check.vue'
import ClearIcon from 'vue-material-design-icons/Close.vue'
import CardDetailEntry from './CardDetailEntry.vue'

export default defineComponent({
	name: 'DueDateSelector',
	components: {
		NcButton,
		ArchiveIcon,
		ClearIcon,
		CardDetailEntry,
		Plus,
		Calendar,
		CalendarCheck,
		CheckIcon,
		NcActions,
		NcActionButton,
		NcActionSeparator,
		NcDateTimePickerNative,
	},
	mixins: [
		readableDate,
	],
	props: {
		card: {
			type: Object,
			default: null,
		},
		canEdit: {
			type: Boolean,
			default: false,
		},
	},
	data() {
		return {
			lang: {
				days: getDayNamesMin(),
				months: getMonthNamesShort(),
				formatLocale: {
					firstDayOfWeek: getFirstDay() === 0 ? 7 : getFirstDay(),
				},
				placeholder: {
					date: t('deck', 'Select Date'),
				},
			},
			format: {
				stringify: this.stringify,
				parse: this.parse,
			},
		}
	},
	computed: {
		duedate: {
			get() {
				return this.card?.duedate ? new Date(this.card.duedate) : null
			},
			set(val) {
				this.$emit('input', val ? new Date(val) : null)
			},
		},

		reminderOptions() {
			const currentDateTime = moment()
			// Same day 18:00 PM (or hidden)
			const laterTodayTime = (currentDateTime.hour() < 18)
				? moment().hour(18)
				: null
			// Tomorrow 08:00 AM
			const tomorrowTime = moment().add(1, 'days').hour(8)
			// Saturday 08:00 AM (or hidden)
			const thisWeekendTime = (currentDateTime.day() !== 6 && currentDateTime.day() !== 0)
				? moment().day(6).hour(8)
				: null
			// Next Monday 08:00 AM
			const nextWeekTime = moment().add(1, 'weeks').day(1).hour(8)
			return [
				{
					key: 'laterToday',
					timestamp: this.getTimestamp(laterTodayTime),
					label: t('deck', 'Later today – {timeLocale}', { timeLocale: laterTodayTime?.format('LT') }),
					ariaLabel: t('deck', 'Set due date for later today'),
				},
				{
					key: 'tomorrow',
					timestamp: this.getTimestamp(tomorrowTime),
					label: t('deck', 'Tomorrow – {timeLocale}', { timeLocale: tomorrowTime?.format('ddd LT') }),
					ariaLabel: t('deck', 'Set due date for tomorrow'),
				},
				{
					key: 'thisWeekend',
					timestamp: this.getTimestamp(thisWeekendTime),
					label: t('deck', 'This weekend – {timeLocale}', { timeLocale: thisWeekendTime?.format('ddd LT') }),
					ariaLabel: t('deck', 'Set due date for this weekend'),
				},
				{
					key: 'nextWeek',
					timestamp: this.getTimestamp(nextWeekTime),
					label: t('deck', 'Next week – {timeLocale}', { timeLocale: nextWeekTime?.format('ddd LT') }),
					ariaLabel: t('deck', 'Set due date for next week'),
				},
			].filter(option => option.timestamp !== null)
		},
	},
	methods: {
		initDate() {
			if (this.duedate === null) {
				// We initialize empty dates with a time once clicked to make picking a day easier
				const now = new Date()
				now.setDate(now.getDate() + 1)
				now.setHours(8)
				now.setMinutes(0)
				now.setMilliseconds(0)
				this.duedate = now
			}
		},
		removeDue() {
			this.duedate = null
			this.$emit('change', null)

		},
		selectShortcut(shortcut) {
			this.duedate = shortcut.timestamp
			this.$emit('change', shortcut.timestamp)
		},
		getTimestamp(momentObject) {
			return momentObject?.minute(0).second(0).millisecond(0).toDate() || null
		},
		changeCardDoneStatus() {
			this.$store.dispatch('changeCardDoneStatus', { ...this.card, done: !this.card.done })
		},
		archiveUnarchiveCard() {
			this.$store.dispatch('archiveUnarchiveCard', { ...this.card, archived: !this.card.archived })
		},
	},
})
</script>
<style scoped lang="scss">
.done-info {
	flex-grow: 1;
}

.done-info--duedate,
.done-info--done {
	display: flex;
	&.dimmed {
		color: var(--color-text-maxcontrast);
	}
}

.completed-button {
	margin-left: auto;
}

.due-actions {
	display: flex;
	align-items: flex-start;
}
</style>
